package com.linkoog.devtools.yaml.yaml2props.action;

import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.ActionUpdateThread;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.linkoog.devtools.yaml.yaml2props.Yaml2Props;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;

/**
 *   Yaml 转 Properties 文件
 */
public class Yaml2propsConvertAction extends AnAction {

    private final static String YAML = "YAML";
    public final static String PROPERTIES_SUFFIX = ".properties";
    private final static String NO_FILE_SELECTED = "No file selected";
    private final static String SELECT_FILE_FIRST = "Please select file first";
    private final static String SUCCESS = "Success";

    public final static String GROUP_DISPLAY_ID = "DevTools.Yaml2props";

    @Override
    public void update(@NotNull AnActionEvent event) {
        super.update(event);
        Presentation presentation = event.getPresentation();
        // get file type
        final String fileType = getFileType(event, false);
        //根据类型动态控制Action的隐藏显示
        if (!StringUtil.isEmpty(fileType) && presentation.isEnabled()) {
            event.getPresentation().setEnabledAndVisible(YAML.equals(fileType));
        } else {
            event.getPresentation().setEnabledAndVisible(false);
        }

    }

    @Override
    public void actionPerformed(@NotNull final AnActionEvent event) {
        // get file type
        final String fileType = getFileType(event, true);
        final PsiFile selectedFile = getSelectedFile(event, true);
        if (StringUtil.isEmpty(fileType) || null == selectedFile) {
            return;
        }
        final VirtualFile file = selectedFile.getVirtualFile();
        if (null == file) {
            Notifications.Bus.notify(new Notification(GROUP_DISPLAY_ID, NO_FILE_SELECTED, SELECT_FILE_FIRST, NotificationType.ERROR));
            return;
        }
        ApplicationManager.getApplication().runWriteAction(() -> {
            try {
                String content = new String(file.contentsToByteArray());
                if (StringUtil.isEmpty(content)) {
                    Notifications.Bus.notify(new Notification(GROUP_DISPLAY_ID, "File content cannot be empty", SELECT_FILE_FIRST, NotificationType.ERROR));
                    return;
                }

                //YAML文件处理
                if (YAML.equals(fileType)) {
                    String yamlContent = Yaml2Props.fromContent(content).convert();
                    file.setCharset(file.getCharset());
                    file.rename(this, file.getNameWithoutExtension() + PROPERTIES_SUFFIX);
                    file.setBinaryContent(yamlContent.getBytes());

                    Notifications.Bus.notify(new Notification(GROUP_DISPLAY_ID, SUCCESS,
                            "YAML file has successfully converted Properties file", NotificationType.INFORMATION));
                } else {
                    Notifications.Bus.notify(new Notification(GROUP_DISPLAY_ID, "Incorrect file selected",
                            "Please select YAML or Properties file first", NotificationType.ERROR));
                }

            } catch (IOException e) {
                Notifications.Bus.notify(new Notification(GROUP_DISPLAY_ID, "Cannot rename file", e.getMessage(), NotificationType.ERROR));
            }
        });
    }


    /**
     * get selected file
     *
     * @param event
     * @param showNotifications
     * @return PsiFile
     */
    public static PsiFile getSelectedFile(AnActionEvent event, boolean showNotifications) {
        //获取当前打开的文件
        PsiFile selectedFile = event.getData(LangDataKeys.PSI_FILE);
        if (selectedFile == null) {
            if (showNotifications) {
                Notifications.Bus.notify(new Notification(GROUP_DISPLAY_ID, "No file selected", "Please select file first", NotificationType.ERROR));
            }
            return null;
        }

        return selectedFile;
    }

    /**
     * get file type
     *
     * @param event
     * @param showNotifications
     */
    public static String getFileType(AnActionEvent event, boolean showNotifications) {
        //获取打开的文件
        PsiFile selectedFile = getSelectedFile(event, showNotifications);
        if (null == selectedFile) {
            return null;
        } else {
            return selectedFile.getFileType().getName();
        }

    }

    @Override
    public @NotNull ActionUpdateThread getActionUpdateThread() {
        return ActionUpdateThread.BGT;
    }
}
